const fs = require('fs');
const path = require('path');
const { writeFile, readFile, fsExistsSync } = require('../util/index');
const defaultGlobal = require('../../config/default/global');
const postcss = require('postcss');
var autoprefixer = require('autoprefixer');
var postcssNested = require('postcss-nested');
var tailwindcss = require('tailwindcss');
var { renderSync } = require('sass');
// 导入 PurgeCSS
const { PurgeCSS } = require('purgecss');

function getTemplateGlobal(template) {
  const newDefaultGlobal = JSON.parse(JSON.stringify(defaultGlobal));
  const diff = JSON.parse(fs.readFileSync(`./src/theme/${template}/lib/config/diff_global.json`, 'utf-8'));
  if (diff.addConfig.length) {
    diff.addConfig.forEach((item) => {
      const keys = item.key.split('-');
      newDefaultGlobal[keys[0]].settings.splice(keys[1], 0, item);
    });
  }
  return newDefaultGlobal;
}

// 获取所有模版
function getThemeAll() {
  const themesFlie = fs.readdirSync('./src/theme');
  const blacklist = [
    '.DS_Store',
    '.git',
    '.gitignore',
    '.vscode',
    'system',
    'component',
    'customtemp39391',
    'customtemp29831',
    'customtemp34484',
    'test',
    'default2.0',
  ];
  const templates = themesFlie.filter((item) => {
    return !blacklist.includes(item) && item.indexOf('customtemp') === -1;
  });
  return templates.map((template) => {
    return {
      name: template,
      global: getTemplateGlobal(template),
    };
  });
}

//获取积木块配置
function getBlockSchema(src) {
  try {
    const content = fs.readFileSync(src, 'utf-8');
    const schemaRegExpStr = /{% schema %}([\s\S]*?){% endschema %}/g;
    const schemBody = content.match(schemaRegExpStr);
    if (schemBody) {
      return JSON.parse(schemBody[0].replace(/({% schema %})|({% endschema %})/g, ''));
    }
    return {};
  } catch (e) {
    console.log(e, src);
  }
}

// 获取模版下积木块
function getThemeSections(theme) {
  const src = `./src/theme/${theme}/sections`;
  const sectionsAll = {};
  if (fs.existsSync(src)) {
    const filenames = fs.readdirSync(src);
    filenames.forEach(function (file) {
      const fileSrc = `${src}/${file}`;
      const schemJson = getBlockSchema(fileSrc);
      const name = file.replace('.liquid', '');
      sectionsAll[name] = schemJson;
    });
  }
  return sectionsAll;
}

// const regex = /{%include\s+([^,|}|\s]+)/g;
// const inputString = "122{%include  name,class:'12'%}{%include '12' %}{%include 12 %}";
// console.log(inputString.match(regex));
// const replacedString = inputString.replace(regex, (match, p1) => {
//   return match.replace(p1,'122')
// });
function getIncludeNames(content) {
  // /{%\s*include\s*(.*),?\s*%}/g)
  var pattern = /{%\s*include\s+([^']+),?\s*%}/g;
  var matches = content.match(pattern);
  if (matches) {
    var includeStrings = matches.map(function (match) {
      return match.replace(/include\s+'([^']+)'/, '$1');
    });
    return [...new Set(includeStrings)];
  } else {
    return [];
  }
}

function buildTailwindcssSass(body) {
  return new Promise((resolve, reject) => {
    postcss([
      tailwindcss({
        purge: ['./src/template/test/**/*.liquid'],
        content: [],
        theme: {
          extend: {},
        },
        plugins: [],
        corePlugins: {
          preflight: false,
        },
      }),
      autoprefixer,
      postcssNested,
    ])
      .process('@import "tailwindcss/base";@import "tailwindcss/components";@import "tailwindcss/utilities";', {
        from: './src/app.css',
        to: './dest/app.css',
      })
      .then((result) => {
        var content = renderSync({ data: body }).css;
        resolve(result.css + content);
      });
  });
}

function buildCss(blocks) {
  return new Promise((resolve) => {
    let allScss = '';
    blocks.forEach((card) => {
      var block = card.router.replace(/\:/g, '/');
      const tempScss = readFile(`./src/theme/component/lib/style/modules/${block}.scss`);
      const indexScss = readFile(`./src/theme/component/lib/style/modules/${card.class}/index.scss`);
      allScss += `${tempScss} ${indexScss}`;
    });
    buildTailwindcssSass(allScss).then((css) => {
      writeFile('./src/template/test/assets/test.css', css.replace(/[\r\n]/g, ''));
    });
    resolve();
  });
}

function snippetsName(path) {
  return path.replace('/', '_');
}

function replaceSnippetsLevels(content, snippetsPaths) {
  snippetsPaths.forEach((path) => {
    if (path.indexOf('/')) {
      content = content.replace(path, snippetsName(path));
    }
  });
  return content;
}

function writeSnippetsFile(snippetsPaths) {
  snippetsPaths.forEach((path) => {
    const content = readFile(`./src/theme/component/snippets/${path}.liquid`);
    if (content) {
      const snippetsPaths = getIncludeNames(content);
      if (snippetsPaths.length) {
        writeSnippetsFile(snippetsPaths);
      }
      writeFile(`./src/template/test/snippets/${snippetsName(path)}.liquid`, replaceSnippetsLevels(content, snippetsPaths));
    }
  });
}

function createTheme(blocks) {
  // const blocks = JSON.parse(fs.readFileSync(`./app/theme/config.json`, "utf-8") || "[]");

  blocks.forEach((card) => {
    var block = card.router.replace(/\:/g, '/');
    var blockFile = `./src/theme/component/sections/${block}.liquid`;
    const content = readFile(blockFile);
    if (content) {
      var snippetsPaths = getIncludeNames(content);
      writeSnippetsFile(snippetsPaths);

      writeFile(`./src/template/test/sections/${card.class}.liquid`, replaceSnippetsLevels(content, snippetsPaths));
    }
  });
  buildCss(blocks);
}

// 递归文件循环生成内容
function getFileIncludeNames(template, names) {
  return names.reduce((total, name) => {
    const content = readFile(`./src/theme/${template}/snippets/${name}.liquid`);
    if (content) {
      const includeNames = getIncludeNames(content);
      if (includeNames.length) {
        getFileIncludeNames(template, includeNames);
        total = [...total, ...includeNames];
      }
      writeFile(`./src/template/test/snippets/${template}_${name}.liquid`, content);
    }
    return total;
  }, names);
}

// 替换内容中的include 添加前缀
function replaceIncludeName(content, replaceValue, verified) {
  // const regex = /{%include\s+([^,|}|\s]+)/g;
  // const inputString = "122{%include  name,class:'12'%}{%include '12' %}{%include 12 %}";
  // console.log(inputString.match(regex));
  // const replacedString = inputString.replace(regex, (match, p1) => {
  //   return match.replace(p1,'122')
  // console.log(inputString.match(regex));
  // });
  let includeNames = new Set();
  const regex = /{%\s+include\s+([^,|}|\s]+)/g;
  let repContent = content.replace(regex, (match, p1) => {
    const name = p1.replace(/['"]/g, '');
    if (verified && verified(name)) {
      includeNames.add(name);
      return match.replace(p1, `"${replaceValue.toLowerCase()}_${name}"`);
    }
    return match;
  });

  return { includeNames: [...includeNames], content: repContent };
}

// 该函数用于处理 Liquid 文件中的 {% include %} 语句。它首先检查输入文件是否存在，然后读取文件内容并替换包含文件名。如果存在对应的 snippet 文件，就将它加入到结果中，否则根据默认包含处理。最后将处理后的内容写入输出文件，并返回处理后的内容和 html 结果的拼接。如果输入文件不存在，则返回空字符串。
function rewrittenIncludeContent(option) {
  // 检查输入文件是否存在
  if (fsExistsSync(option.input.src)) {
    // 读取输入文件内容并替换包含文件名
    const { includeNames, content } = replaceIncludeName(readFile(option.input.src), option.input.name, (name) => {
      // 检查是否存在对应的snippet文件
      if (fsExistsSync(`./src/theme/${option.input.name}/snippets/${name}.liquid`)) {
        return true;
      }
      // 默认包含处理
      option.defaultInclude && option.defaultInclude(name);
      return false;
    });
    let html = '';
    // 如果存在包含文件名列表
    if (includeNames.length) {
      // 递归处理每个包含文件，并将结果拼接到html中
      html = includeNames.reduce((total, item) => {
        total += rewrittenIncludeContent({
          input: {
            src: `./src/theme/${option.input.name}/snippets/${item}.liquid`,
            name: option.input.name,
          },
          output: {
            src: `./src/theme/${option.output.name}/snippets/${option.input.name.toLowerCase()}_${item}.liquid`,
            name: option.output.name,
          },
          defaultInclude: option.defaultInclude,
        });
        return total;
      }, '');
    }
    // 将处理后的内容写入输出文件
    writeFile(option.output.src, content);
    // 返回处理后的内容和html结果的拼接
    return content + html;
  }

  // 如果输入文件不存在，返回空字符串
  return '';
}

// 该函数使用 PurgeCSS 库，根据指定的 Liquid 和 CSS 文件进行CSS 清理，返回清理后的 CSS 内容。
async function purgeCSSLiquid(section, templateName = 'test') {
  // 创建 PurgeCSS 配置对象

  const cssBody = readFile(`./src/theme/${section.template}/assets/${section.template}_theme.css`);
  let sectionOption = {
    input: {
      src: `./src/theme/${section.template}/sections/${section.section}.liquid`,
      name: section.template,
    },
    output: {
      src: `./src/theme/${templateName}/sections/${section.template.toLowerCase()}_${section.section}.liquid`,
      name: templateName,
    },
    defaultInclude(name) {
      console.log('引用默认',name);
    },
  };
  const sectionHtml = rewrittenIncludeContent(sectionOption);
  const purgeCSSConfig = {
    content: [
      {
        raw: sectionHtml,
        extension: 'html',
      },
    ], // 指定需要扫描的文件，可以根据项目需要添加更多文件或目录
    css: [
      {
        raw: cssBody,
        extension: 'css',
      },
    ], // 指定需要处理的 CSS 文件
    // 这里可以添加其他配置选项
    safelist: ['img', 'button'],
    blocklist: ['container'],
  };

  // 使用 PurgeCSS API 进行优化
  const result = await new PurgeCSS().purge(purgeCSSConfig);

  writeFile(`./src/theme/${templateName}/lib/style/modules/${section.template.toLowerCase()}_${section.section}.scss`, result[0].css);
}
// 生成模版
async function createTemplate(sections) {
  try {
    for (let i = 0; i < sections.length; i++) {
      const section = sections[i];
      await purgeCSSLiquid(section);
    }
    return true;
  } catch (error) {
    return error;
  }

  // let css = sections.map(async (section) => {
  //     // 创建 PurgeCSS 配置对象
  //     const purgeCSSConfig = {
  //         content: [
  //             {
  //                 raw: readFile(`./src/theme/${section.template}/sections/${section.section}.liquid`),
  //                 extension: "html"
  //             }
  //         ], // 指定需要扫描的文件，可以根据项目需要添加更多文件或目录
  //         css: [
  //             {
  //                 // raw:'body { margin: 0 }',
  //                 raw: readFile(`./src/theme/${section.template}/assets/${section.template}_theme.css`),
  //                 extension: "css"
  //             }
  //         ] // 指定需要处理的 CSS 文件
  //         // 这里可以添加其他配置选项
  //     };

  //     // 使用 PurgeCSS API 进行优化
  //     const result = await new PurgeCSS().purge(purgeCSSConfig);

  //     return result[0].css;
  // });
}

module.exports = { getThemeAll, getBlockSchema, createTheme, getThemeSections, createTemplate };
